﻿using System;
using System.Linq;
using System.Web.Mvc;
using Framework.Admin;
using Framework.DataAccess;
using Framework.Util.Cryptography;
using Framework.Util.EmailUtil;
using MvcContrib.Pagination;
using Project.DAL.Repository;
using Project.Domain.Entities;
using Project.Resource.User;
using Project.WebUI.Models;

namespace Project.WebUI.Controllers
{
    public class UserController : Controller
    {
        #region "private"
        
        private readonly IUserRepository _userRepository;
        private readonly IDepositRepository _depositRepository;
        private readonly IWithDrawRepository _withDrawRepository;
        private readonly ICommonRepository _commonRepository;
        private readonly IUserService _userService;
        private readonly ICountryRepository _countryRepository;
        private readonly IContactRepository _contactRepository;
        private readonly IUnitOfWork _unitOfWork;          
        private readonly IUserbetRepository _userbetRepository;
        private readonly IStoreSecureRepositoty _storeSecureRepositoty;

        public UserController(
            IUserRepository userRepository,
            IDepositRepository depositRepository,
            IWithDrawRepository withDrawRepository,
            ICommonRepository commonRepository,
            IUserService userService,            
            ICountryRepository countryRepository,
            IContactRepository contactRepository,
            IUnitOfWork unitOfWork,            
            IUserbetRepository userbetRepository,
            IStoreSecureRepositoty storeSecureRepositoty)
        {            
            _userRepository = userRepository;
            _depositRepository = depositRepository;
            _withDrawRepository = withDrawRepository;
            _commonRepository = commonRepository;
            _userService = userService;
            _countryRepository = countryRepository;
            _contactRepository = contactRepository;
            _unitOfWork = unitOfWork;
            _storeSecureRepositoty = storeSecureRepositoty;
            _userbetRepository = userbetRepository;
        }

        #endregion        

        #region "Account Info"
        [ChildActionOnly]
        public ActionResult AccountInfo()
        {
            if (Request.IsAuthenticated)
            {
                var user = _userRepository.GetUserByName(User.Identity.Name);
                var contactInfo = new ContactInfo()
                {
                    UserName = user.UserName,
                    Balance = user.Balance.ToString()
                };
                return PartialView("_accountLogIn", contactInfo);
            }
            else
            {
                return PartialView("_NotLogIn");
            }           
        }

        #endregion

        #region "Action login"
        public ActionResult Login()
        {            
            return View();
        }
        [HttpPost]
        [ValidateInput(true)]        
        public ActionResult Login(FormCollection logonmodel)
        {
            if (User.Identity.IsAuthenticated)
            {
                //login
                return Content("2");
            }
            var userName = Request.Params["user"];
            var passWord = Request.Params["pass"];
            if (_userService.CompareUsername(userName))
            {
                var password = _userService.ComparePassWord(passWord, userName);
                if (password)
                {
                    if (!_userRepository.Checkactive(userName))
                    {
                        // return 3 to not active
                        return Content("3");
                    }
                    var user = _userRepository.Get(u => u.UserName.Equals(userName));
                    Authentication.SigIn(userName, true);
                    Session.Add("userName", userName);
                    Session.Add("balance", user.Balance);
                    //return 1 to success
                    return Content("1");
                }
                return Content("0");
            }
            return Content("0");
        }
            
        public ActionResult LogOut()
        {
            Authentication.SignOut();
            Session.Abandon();
            return RedirectToAction("Index", "Home");
        }

        #endregion

        #region "Action Register"

        public JsonResult CheckUserName(string username)
        {            
            return Json(_userService.CompareUsername(username) ? "0" : "1", JsonRequestBehavior.AllowGet);
        }

        public JsonResult CheckEmail(string email)
        {            
            return Json(_userService.CheckEmail(email) ? "0" : "1", JsonRequestBehavior.AllowGet);
        }
       

        [HttpGet]
        public ActionResult Register()
        {
            if (Session["userName"] != null)
            {
                return RedirectToAction("index", "Home");
            }

            var lang = Session["Culture"];
            int selectedCountry;            
            if(lang==null || lang.Equals("en"))
            {
                selectedCountry = _countryRepository.Get(c => c.CountryName.Equals("United States")).CountryId;
            }
            else 
            {
                selectedCountry = _countryRepository.Get(c => c.CountryName.Equals("Vietnam")).CountryId;
            }

            if (ViewBag.ListCountries == null)
            {                
                ViewBag.ListCountries = new SelectList(_countryRepository.GetAll().ToList(), "CountryId",
                                                       "CountryName", selectedCountry);
            }            
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [ValidateInput(true)]
        public ActionResult Register(UserRegisteModel registerModel)
        {
            var lang = Session["Culture"];
            int selectedCountry;
            if (lang == null || lang.Equals("en"))
            {
                selectedCountry = _countryRepository.Get(c => c.CountryName.Equals("United States")).CountryId;
            }
            else
            {
                selectedCountry = _countryRepository.Get(c => c.CountryName.Equals("Vietnam")).CountryId;
            }

            if (ViewBag.ListCountries == null)
            {
                ViewBag.ListCountries = new SelectList(_countryRepository.GetAll().ToList(), "CountryId",
                                                       "CountryName", selectedCountry);
            }

            if (ModelState.IsValid)
            {
                if (!_userService.CheckAccountLr(registerModel.LrAccount))
                {
                    ModelState.AddModelError("LrAccount", RegisterResource.InvalidLrAccount);
                    return View(registerModel);
                }

                if (registerModel.UserName.Contains("admin") || registerModel.UserName.Contains("administrator") ||
                    registerModel.UserName.Contains("administrators") || registerModel.UserName.Contains("admiN") ||
                    registerModel.UserName.Contains("Admin") || registerModel.UserName.Contains("aDmin"))
                {
                    ModelState.AddModelError("UserName", RegisterResource.InvalidUserName);
                    return View(registerModel);
                }
                //if return true is exsist user
                if (_userService.CompareUsername(registerModel.UserName))
                {
                    ModelState.AddModelError("UserName", RegisterResource.ExistsUserName);
                    return View(registerModel);
                }
                if (_userService.CheckEmail(registerModel.Email))
                {
                    ModelState.AddModelError("Email", RegisterResource.ExsistsEmail);
                    return View(registerModel);
                }
                var passWord = CryptographyManager.Encrypt(registerModel.Password);
                var usermodel = new User
                    {
                        UserName = registerModel.UserName,
                        Email = registerModel.Email,
                        Balance = 0.0M,
                        Password = passWord,
                        LrAccount = registerModel.LrAccount,
                        Active = false,
                        ActiveCode = Guid.NewGuid(),
                        CreatedTime = DateTime.Now,
                        IsAdmin = false,
                        FirstName = registerModel.FirstName,
                        LastName = registerModel.LastName,
                        Country = Request.Params["CountryId"],
                        Address = registerModel.Address,
                        Phone = registerModel.Phone
                    };
                _userRepository.Add(usermodel);
                _userRepository.SaveChanges();
                ViewBag.Status = "1";
                //SendMail.GetInstant().SendEmail(usermodel.UserName,usermodel.Email,EmailContent.RegisterTitle(),EmailContent.RegisterContent(usermodel.UserName, usermodel.ActiveCode.ToString()));
                return View();
            }            
            return View(registerModel);
        }

        #endregion

        #region "Action ChangPassword"

        [HttpGet]
        public ActionResult ChangePassword()
        {
            if (!Request.IsAuthenticated)
            {
                return RedirectToAction("Login");
            }
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [ValidateInput(true)]
        public ActionResult ChangePassword(ChangePasswordModel userModel)
        {
            if (!Request.IsAuthenticated)
            {
                return View("NotFound");
            }
            var userName = User.Identity.Name;                        
            if (ModelState.IsValid)
            {                
                var user = _userRepository.Get(u=>u.UserName.Equals(userName));
                if (user == null)
                    return RedirectToAction("Index", "Home");

                if (_userService.ComparePassWord(userModel.CurrentPassword, user.UserName))
                {
                    user.Password = CryptographyManager.Encrypt(userModel.Password);
                    _userRepository.SaveChanges();

                    if (ViewBag.success == null)
                        ViewBag.success = "1";
                    return View();
                }
                ModelState.AddModelError("CurrentPassword", ChangePasswordResource.ChangePasswordFailed);
                return View(userModel);
            }
            return View(userModel);
        }
        #endregion

        #region "Action ActiveUser"
        [HttpGet]
        public ActionResult Active(string activeCode, string userName)
        {
            //url=domain/user/active/username/activecode
            var userActive = new User();            
            if (activeCode == null || userName == null)
            {
                //=2 faile link
                ViewBag.Status = "4";
                return View();
            }
            //get user by activecode
            var useractive =
                _userRepository.GetAllUser()
                    .FirstOrDefault(u => u.ActiveCode.ToString().Equals(activeCode) &&u.UserName.Equals(userName) && u.Active == false);

            //if exsist user continue check expire activelink
            if (useractive != null)
            {
                //Link expired
                if ((DateTime.Now - useractive.CreatedTime).TotalDays > 5)
                {
                    ViewBag.Status = "3";
                    return View();
                }

                //link not expire
                ViewBag.Status = "1";
                return View();
            }

            //user not exsist in system
            ViewBag.Status = "4";
            return View();
        }

        #endregion

        #region "Deposit"
        [HttpGet]
        public ActionResult Deposit()
        {
            if (!Request.IsAuthenticated || Session["admin"] != null)
            {
                return RedirectToAction("index", "Home");
            }
            var storeConfig = _storeSecureRepositoty.GetAll().FirstOrDefault();
            if (storeConfig != null)
            {
                ViewBag.Payto = storeConfig.ConfigStorePayto;
                ViewBag.StoreName = storeConfig.ConfigMachentStoreName;
                ViewBag.SecureWord = storeConfig.ConfigSecureWord;
            }
            var user = _userRepository.Get(u => u.UserName == User.Identity.Name);
            ViewBag.PayFrom = user.LrAccount;
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [ValidateInput(true)]
        public ActionResult Deposit(FormCollection fc)
        {
            var storeSecure = _storeSecureRepositoty.Get(null);
            var user = _userRepository.GetUserByName(User.Identity.Name);
            var configStorePayto = storeSecure.ConfigStorePayto;
            var configMachentStoreName = storeSecure.ConfigMachentStoreName;
            var configSecureWord = storeSecure.ConfigSecureWord;
            var lrPaidto = Convert.ToString(fc["lr_paidto"]);
            var lrPaidby = Convert.ToString(fc["lr_paidby"]);
            var lrAmount = fc["lr_amnt"];
            var lrStore = Convert.ToString(fc["lr_store"]);
            var lrTransfer = fc["lr_transfer"];
            var lrCurrency = Convert.ToString(fc["lr_currency"]);
            var lrEncrypted = Convert.ToString(fc["lr_encrypted"]);
            var stringTo = lrPaidto + ":" + lrPaidby + ":" + lrStore + ":" + lrAmount + ":" + lrTransfer + ":" +
                           lrCurrency + ":" + configSecureWord;
            var hasString = _userService.EncryptSha256(stringTo);

            if (lrPaidto != null && lrPaidto.Equals(configStorePayto)
                && lrStore != null && lrStore.Equals(configMachentStoreName) && hasString.Equals(lrEncrypted))
            {
                if (user != null)
                {
                    user.Balance += Convert.ToDecimal(lrAmount);
                    /*if (user.UserIdRefer != null)
                    {
                        var userParent = _db.ProUsers.FirstOrDefault(p => p.Num_PIN == user.UserIdRefer);
                        if (userParent != null)
                        {
                            userParent.Amount += 0.1M;
                        }
                        var earning = new Earning
                        {
                            UserId = user.UserId,
                            MoneyEarning = 0.1M,
                            CreatedTime = DateTime.Now
                        };
                        _db.AddToEarnings(earning);
                        _db.SaveChanges();
                    }*/

                    var deposit = new Deposit
                    {
                        UserId = user.UserId,
                        Amount = Convert.ToDecimal(lrAmount),
                        CreatedTime = DateTime.Now,                       
                        Batch = Convert.ToInt64(lrTransfer)
                    };
                    _depositRepository.Add(deposit);
                    _unitOfWork.Commit();                   
                }
            }
            if (ViewBag.user == null && ViewBag.status == null && ViewBag.amount == null)
            {
                ViewBag.status = "true";
                ViewBag.amount = lrAmount;
                if (user != null)
                    ViewBag.user = user.UserName;
            }
            return View();
        }        
        #endregion

        #region "WithDraw"
        public ActionResult Withdraw()
        {
            if (!Request.IsAuthenticated)
            {
                return RedirectToAction("Index", "Home");
            }
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Withdraw(WithdrawModel withdrawmodel)
        {
            if (!Request.IsAuthenticated)
            {
                return RedirectToAction("Index", "Home");
            }
            var user = _userRepository.Get(u => u.UserName == User.Identity.Name);
            if (ModelState.IsValid)
            {
                if (user.Balance < withdrawmodel.lr_amnt)
                {
                    ModelState.AddModelError("lr_amnt", WithDrawResource.InvalidBalance);
                }
                else
                {
                    var withdraw = new WithDraw()
                        {
                            UserId = user.UserId,
                            Amount = withdrawmodel.lr_amnt,
                            CreatedTime = DateTime.Now,
                            Approved = false,
                        };
                    if (_withDrawRepository.Add(withdraw))
                    {
                        _withDrawRepository.SaveChanges();
                        user.Balance -= withdrawmodel.lr_amnt;                        
                        _userRepository.SaveChanges();
                        ViewBag.success = "1";
                        return View();
                    }

                    ViewBag.success = "0";
                    return View();
                }
            }
            return View(withdrawmodel);
        }

        public ActionResult ApproveWithdraw(int id)
        {
            try
            {
                var withdraw = _withDrawRepository.Get(w => w.WithDrawId == id);
                withdraw.Approved = true;
               _unitOfWork.Commit();
                return Content("1");
            }
            catch(Exception ex)
            {                
                return Content("0");
            }
            
        }
        #endregion

        /*#region "Affilitates"
        public ActionResult Affilitates(int? id)
        {            
            if (id == null)
            {
                if (!Request.IsAuthenticated)
                    return View();

                var user = _userRepository.GetUserByName(User.Identity.Name);
                var checkChild = _db.ProUsers.Include("Earnings").Where(ch => ch.UserIdRefer == user.Num_PIN);
                if (ViewBag.pin == null)
                {
                    ViewBag.pin = user.Num_PIN;
                }
                return View(checkChild);
            }

            if (!Request.IsAuthenticated)
            {
                Session.Add("refer", id);
                if (HttpContext.Request.UrlReferrer != null)
                {
                    var urlRefer = HttpContext.Request.UrlReferrer.ToString();
                    Session.Add("urlrefer", urlRefer);
                }
                return RedirectToAction("register");
            }

            return RedirectToAction("index", "Home");
        }

        #endregion*/
        
        #region "reference"
        public ActionResult Reference(int? id)
        {
            if (id != null)
            {
                if (!Request.IsAuthenticated)
                {
                    Session.Add("refer", id);
                    return RedirectToAction("register");
                }
                return RedirectToAction("index", "Home");
            }

            if (!Request.IsAuthenticated)
            {
                return View();
            }

            var user = _userRepository.GetUserByName(User.Identity.Name);
            return View(user);

        }

        #endregion

        #region "forgot"
        [HttpGet]
        public  ActionResult ForgotPassword()
        {
            return View();
        }
        [HttpPost]        
        [ValidateInput(true)]
        public ActionResult ForgotPassword(Forgot forgotModel)
        {
            if (Request.IsAuthenticated)
            {
                return Content("2");
            }
            var userName = Request.Params["user"];
            var email = Request.Params["email"];                        
            var user = _userRepository.Get(u => u.UserName.Equals(userName) && u.Email.Equals(email));
            if (user != null)
            {
                var passnewNoEn = _userService.ForgotPass();
                user.Password = CryptographyManager.Encrypt(passnewNoEn);
                _userRepository.SaveChanges();
                //SendMail.GetInstant().SendEmail(user.UserName, user.Email, EmailContent.ChangePassowrdTitle(),
                //                      EmailContent.ChangePasswordContent(user.UserName, user.UserName, passnewNoEn));
                return Content("1");
            }
            return Content("0");         
        }
        #endregion

        #region "User Contact"

        [HttpGet]
        public ActionResult Contacts()
        {
            var culture = "";
            if (Session["Culture"] != null && Session["Culture"].ToString().Equals("vi-VN"))
            {
                culture = "vi-VN";
            }
            var contentHeder = _commonRepository.Get(c => c.Type == "contact_top");
            ViewBag.contentHeder = culture=="vi-Vn" ? contentHeder.Content : contentHeder.ContentEn;
            ViewBag.ContactType = culture == "vi-VN" ? new SelectList(_commonRepository.GetMany(c => c.Type == "contact_type"), "CommonId", "Content") : new SelectList(_commonRepository.GetMany(c => c.Type == "contact_type"), "CommonId", "ContentEn");
            return View();
        }

        [HttpPost]
        [ValidateInput(true)]
        [ValidateAntiForgeryToken]
        public ActionResult Contacts(ContactModel contactModel, FormCollection fc)
        {
            var culture = "";
            if (Session["Culture"] != null && Session["Culture"].ToString().Equals("vi-VN"))
            {
                culture = "vi-VN";
            }
            var contentHeder = _commonRepository.Get(c => c.Type == "contact_top");
            ViewBag.contentHeder = culture == "vi-VN" ? contentHeder.Content : contentHeder.ContentEn;
            ViewBag.ContactType = culture == "vi-VN" ? new SelectList(_commonRepository.GetMany(c => c.Type == "contact_type"), "CommonId", "Content") 
                : new SelectList(_commonRepository.GetMany(c => c.Type == "contact_type"), "CommonId", "ContentEn");
            if (ModelState.IsValid)
            {
                var contact = new Contact
                {
                    CommonId = Convert.ToInt32(fc["CommonId"]),
                    Email = contactModel.Email,
                    Body = contactModel.Body,
                    CreatedTime = DateTime.Now,
                    Active = false
                };
                _contactRepository.Add(contact);   
                _contactRepository.SaveChanges();
                ViewBag.status = "success";
            }
            return View();
        }

        #endregion

        #region "ListDeposit && WithDraw"

        public ActionResult ListDeposit(int page)
        {
            var listDeposit = _depositRepository.GetMany(null,d=>d.OrderBy(t=>t.CreatedTime), "User").Take(50);
            if (listDeposit != null)
                return PartialView("_ListDeposit", listDeposit.AsPagination(page, 10));
            return View("Error");
        }

        public ActionResult ListWithdraw(int page)
        {
            var listWithdraw = _withDrawRepository.GetMany(null, d => d.OrderBy(t => t.CreatedTime), "User").Take(50);
            if (listWithdraw != null)
                return PartialView("_ListWithdraw", listWithdraw.AsPagination(page, 10));
            return View("Error");
        }

        #endregion

        #region ProfileUser

        public ActionResult Profile()
        {
            if(!Request.IsAuthenticated)
            {
                return RedirectToAction("Login");
            }
            return View();
        }        
        
        #endregion

        #region UserInfo
        public ActionResult UserInfo()
        {

            var lang = Session["Culture"];
            int selectedCountry;
            if (lang == null || lang.Equals("en"))
            {
                selectedCountry = _countryRepository.Get(c => c.CountryName.Equals("United States")).CountryId;
            }
            else
            {
                selectedCountry = _countryRepository.Get(c => c.CountryName.Equals("Vietnam")).CountryId;
            }

            if (ViewBag.ListCountries == null)
            {
                ViewBag.ListCountries = new SelectList(_countryRepository.GetAll().ToList(), "CountryId",
                                                       "CountryName", selectedCountry);
            }
            if (!Request.IsAuthenticated)
            {
                return RedirectToAction("Login");
            }
            var userName=User.Identity.Name;
            var userInfo = _userRepository.Get(u => u.UserName.Equals(userName));
            var userInforDTO = new UserInfoDTO()
            {
                UserName = userInfo.UserName,
                FirstName = userInfo.FirstName,
                LastName = userInfo.LastName,
                Phone = userInfo.Phone,
                LrAccount = userInfo.LrAccount,
                Email = userInfo.Email,
                Address = userInfo.Address,                
                Birthday=userInfo.BirthDay
            };

            return PartialView("_Maincontent", userInforDTO);
        }

        [HttpPost]
        public ActionResult Profile(UserInfoDTO userInfoDTO)
        {
            if (!Request.IsAuthenticated)
            {
                return RedirectToAction("LogIn");
            }

            if (ModelState.IsValid)
            {
                var userName = User.Identity.Name;
                var userInfo = _userRepository.Get(u => u.UserName.Equals(userName));
                if (userInfo == null)
                {
                    return RedirectToAction("LogIn");
                }
                userInfo.FirstName = userInfoDTO.FirstName;
                userInfo.LastName = userInfoDTO.LastName;
                userInfo.BirthDay = Request.Params["txtbirthday"];
                userInfo.Country = Request.Params["CountryId"];
                userInfo.Phone = Request.Params["txtphone"];
                userInfo.Address = userInfoDTO.Address;
                _userRepository.SaveChanges();
            }
            return View("Profile", userInfoDTO);
        }
        #endregion

        public ActionResult AjaxDeposit(int page)
        {
            var userName=User.Identity.Name;
            var user = _userRepository.Get(u => u.UserName.Equals(userName));
            var listDeposit = _depositRepository.GetMany(d => d.UserId.Equals(user.UserId),
                                                             d =>
                                                             d.OrderByDescending(t => t.CreatedTime).ThenBy(t => t.Amount));
            ViewBag.result = listDeposit.Count();
            ViewBag.page = page;
            if (page == 1)
            {
                ViewBag.start = 0;
            }
            else
            {
                ViewBag.start = (page - 1) * 10;
            }
            return PartialView("_DepositContent", listDeposit.AsPagination(page, 10));
        }

        public ActionResult AjaxWithDraw(int page)
        {            
            var userName = User.Identity.Name;
            var user = _userRepository.Get(u => u.UserName.Equals(userName));
            var listWithDraw = _withDrawRepository.GetMany(d => d.UserId.Equals(user.UserId),
                                                             d =>
                                                             d.OrderByDescending(t => t.CreatedTime).ThenBy(t => t.Amount));
            ViewBag.result = listWithDraw.Count();
            ViewBag.page = page;
            if (page == 1)
            {
                ViewBag.start = 0;
            }
            else
            {
                ViewBag.start = (page - 1) * 10;
            }
            return PartialView("_WithDrawContent", listWithDraw.AsPagination(page, 10));
        }

        public ActionResult BetHistory()
        {
            return View();
        }

        public ActionResult AjaxBet(int page)
        {            
            var userName = User.Identity.Name;
            var user = _userRepository.Get(u => u.UserName.Equals(userName));
            var listWithDraw = _userbetRepository.GetMany(d => d.UserId.Equals(user.UserId),
                                                             d =>
                                                             d.OrderByDescending(t => t.CreatedTime),"BetDetail");
            ViewBag.result = listWithDraw.Count();
            ViewBag.page = page;
            if (page == 1)
            {
                ViewBag.start = 0;
            }
            else
            {
                ViewBag.start = (page - 1) * 10;
            }
            return PartialView("_BetHistoryContent", listWithDraw.AsPagination(page, 10));
        }
        public ActionResult Help()
        {                       
            var helpContent = _commonRepository.Get(c => c.Type.Equals("help_content"));
            return View(helpContent);
        }
    }
}
